package com.sjsu.CMPE226.partitioned.jdbc.repo;

import java.util.List;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sjsu.CMPE226.JDBC.config.PartionedConnection;
import com.sjsu.CMPE226.normalized.jdbc.data.Observation;

public class RepositoryDatabase implements Repository {

	protected static Logger logger = LoggerFactory.getLogger("database");

	@Override
	public List<Observation> findAllObservationsForDate() {
		List<Observation> obs = null;
		Connection conn = null;
		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareSelectAllObservationsForDate(conn);
			ResultSet rs = ps.executeQuery();
			obs = ObservationMapper.decodeAllObservations(rs);
			ps.close();

		} catch (Exception ex) {
			logger.error("Exception: Failed to find all Observations", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return obs;
	}

	@Override
	public List<Observation> findAllObservationsForState() {
		List<Observation> obs = null;
		Connection conn = null;

		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareSelectAllObservationsForState(conn);
			ResultSet rs = ps.executeQuery();
			obs = ObservationMapper.decodeAllObservations(rs);

			ps.close();

		} catch (Exception ex) {
			logger.error(
					"Exception: Failed to find all Observations for State", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return obs;
	}

	@Override
	public List<Observation> findAllObservationsForNetwork() {
		List<Observation> obs = null;
		Connection conn = null;

		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareSelectAllObservationsForNetwork(conn);
			ResultSet rs = ps.executeQuery();
			obs = ObservationMapper.decodeAllObservations(rs);

			ps.close();
		} catch (Exception ex) {
			logger.error(
					"Exception: Failed to find all Observations for Network",
					ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return obs;
	}

	@Override
	public List<Observation> findAllObservationsForNetworkAndProvider() {
		List<Observation> obs = null;
		Connection conn = null;

		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareSelectAllObservationsForNetworkAndProvider(conn);
			ResultSet rs = ps.executeQuery();
			obs = ObservationMapper.decodeAllObservations(rs);

			ps.close();
		} catch (Exception ex) {
			logger.error(
					"Exception: Failed to find all Observations for Network and Provider",
					ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return obs;
	}

	@Override
	public int updateStationsForSecondaryStation() {
		Connection conn = null;
		int updatedRows = 0;
		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = StationMapper
					.prepareUpdateStationsForSecondaryStation(conn);
			updatedRows = ps.executeUpdate();

			ps.close();
		} catch (Exception ex) {
			logger.error("Exception: Could not update Stations", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return updatedRows;
	}

	@Override
	public int updateObservationsForSeaLevelPressure() {
		int updatedRows = 0;
		Connection conn = null;

		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareUpdateObservationsForSeaLevelPressure(conn);
			updatedRows = ps.executeUpdate();

			ps.close();
		} catch (Exception ex) {
			logger.error("Exception: Failed to update Observations", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return updatedRows;
	}

	@Override
	public int deleteObservationsForAltimeter() {
		int deletedRows = 0;
		Connection conn = null;

		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = ObservationMapper
					.prepareDeleteObservationsForAltimeter(conn);
			deletedRows = ps.executeUpdate();

			ps.close();
		} catch (Exception ex) {
			logger.error("Exception: Failed to delete Observations", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return deletedRows;
	}

	@Override
	public int deleteStationsForLatitude() {
		int deletedRows = 0;
		Connection conn = null;
		
		try {
			conn = PartionedConnection.getConnection();
			PreparedStatement ps = StationMapper.prepareDeleteStationsForLatitude(conn);
			deletedRows = ps.executeUpdate();
			
			ps.close();
		} catch (Exception ex) {
			logger.error("Exception: Failed to delete Stations", ex);
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		return deletedRows;
	}

}
